package com.ruoyi.article.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.ruoyi.article.domain.ZArticle;
import com.ruoyi.article.domain.ZPraiseLog;
import com.ruoyi.article.domain.vo.reviewData;
import com.ruoyi.article.mapper.ZPraiseLogMapper;
import com.ruoyi.article.service.IZArticleService;
import com.ruoyi.article.service.IZPraiseLogService;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.article.mapper.ZArticleReviewMapper;
import com.ruoyi.article.domain.ZArticleReview;
import com.ruoyi.article.service.IZArticleReviewService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 评论Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-12-02
 */
@Service
public class ZArticleReviewServiceImpl extends ServiceImpl<ZArticleReviewMapper,ZArticleReview> implements IZArticleReviewService
{
    @Autowired
    private ZArticleReviewMapper zArticleReviewMapper;

    @Autowired
    private IZArticleService zArticleService;

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private IZPraiseLogService zPraiseLogService;
    @Autowired
    private ZPraiseLogMapper zPraiseLogMapper;
    /**
     * 查询评论
     * 
     * @param id 评论主键
     * @return 评论
     */
    @Override
    public ZArticleReview selectZArticleReviewById(Long id)
    {
        return zArticleReviewMapper.selectZArticleReviewById(id);
    }

    /**
     * 查询评论列表
     * 
     * @param zArticleReview 评论
     * @return 评论
     */
    @Override
    public List<ZArticleReview> selectZArticleReviewList(ZArticleReview zArticleReview)
    {
        return zArticleReviewMapper.selectZArticleReviewList(zArticleReview);
    }

    /**
     * 新增评论
     * 
     * @param zArticleReview 评论
     * @return 结果
     */
    @Override
    public int insertZArticleReview(ZArticleReview zArticleReview)
    {
        return zArticleReviewMapper.insertZArticleReview(zArticleReview);
    }

    /**
     * 修改评论
     * 
     * @param zArticleReview 评论
     * @return 结果
     */
    @Override
    public int updateZArticleReview(ZArticleReview zArticleReview)
    {
        return zArticleReviewMapper.updateZArticleReview(zArticleReview);
    }

    /**
     * 批量删除评论
     * 
     * @param ids 需要删除的评论主键
     * @return 结果
     */
    @Override
    public int deleteZArticleReviewByIds(Long[] ids)
    {
        return zArticleReviewMapper.deleteZArticleReviewByIds(ids);
    }

    /**
     * 删除评论信息
     * 
     * @param id 评论主键
     * @return 结果
     */
    @Override
    public int deleteZArticleReviewById(Long id)
    {
        return zArticleReviewMapper.deleteZArticleReviewById(id);
    }

    @Override
    public TableDataInfo selectReviewTree(ZArticleReview zArticleReview) {
        IPage<ZArticleReview> pageReview = new Page<>(zArticleReview.getPageCurrent(),zArticleReview.getPageSize());
        LambdaQueryWrapper<ZArticleReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ZArticleReview::getParentId,0);
        wrapper.eq(ObjectUtils.isNotNull(zArticleReview.getContentId()),ZArticleReview::getContentId,zArticleReview.getContentId());
        IPage<ZArticleReview> zArticleReviewIPage = zArticleReviewMapper.selectPage(pageReview, wrapper);
        List<ZArticleReview> records = zArticleReviewIPage.getRecords();
        for (ZArticleReview record : records) {
            SysUser sysUser = sysUserMapper.selectUserById(record.getUserId());
            record.setUserImg(sysUser.getAvatar());
            LambdaQueryWrapper<ZArticleReview> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(ZArticleReview::getParentId,record.getId());
            List<ZArticleReview> zArticleReviews = zArticleReviewMapper.selectList(wrapper1);
            record.setChildren(zArticleReviews);
            for (ZArticleReview articleReview : zArticleReviews) {
                SysUser user = sysUserMapper.selectUserById(articleReview.getUserId());
                articleReview.setUserImg(user.getAvatar());
            }

        }
        TableDataInfo dataInfo = new TableDataInfo();
        dataInfo.setCode(HttpStatus.SUCCESS);
        dataInfo.setMsg("查询成功");
        dataInfo.setRows(records);
        dataInfo.setTotal(zArticleReviewIPage.getTotal());
        return dataInfo;
    }

    //新增一级评论
    @Override
    public int insertReview(ZArticleReview zArticleReview) {
        //接收评论文章的id和内容
        Long articleId = zArticleReview.getContentId();
        String commentDetails = zArticleReview.getCommentDetails();
        ZArticleReview review = new ZArticleReview();
        review.setContentId(articleId);
        review.setCommentDetails(commentDetails);
        review.setParentId(0L);
        review.setUserId(SecurityUtils.getUserId());
        review.setUserName(SecurityUtils.getUsername());
        review.setLikeNum(0L);
        review.setCommentDate(new Date());
        //判断是不是作者
        ZArticle zArticle = zArticleService.getById(articleId);
        //如果评论是作者
        if (zArticle.getAuthorId().equals(SecurityUtils.getUserId())){
            review.setContentFlag(1L);
        }else {
            review.setContentFlag(2L);
        }
        zArticleReviewMapper.insert(review);
        //文章评论数量+1
        zArticle.setEvaluate(zArticle.getEvaluate()+1);

        return zArticleService.updateById(zArticle) ? 1 : -1;
    }

    @Override
    public int saveReview(ZArticleReview zArticleReview) {
        //得到评论内容和被回复的评论id
        String commentDetails = zArticleReview.getCommentDetails();
        Long id = zArticleReview.getId();

        ZArticleReview r = new ZArticleReview();

        //查询所要回复的评论
        ZArticleReview review = zArticleReviewMapper.selectById(id);
        r.setContentId(review.getContentId());
        r.setUserId(SecurityUtils.getUserId());
        r.setUserName(SecurityUtils.getUsername());
        r.setCommentDetails(commentDetails);
        r.setCommentDate(new Date());
        //回复的评论id
        r.setReplyCommentId(review.getId());
        r.setReplyUserId(review.getUserId());
        r.setReplyUserName(review.getUserName());

        //判断是不是作者
        ZArticle zArticle = zArticleService.getById(review.getContentId());
        //如果评论是作者
        if (zArticle.getAuthorId().equals(SecurityUtils.getUserId())){
            r.setContentFlag(1L);
        }else {
            r.setContentFlag(2L);
        }

        //判断是回复一级评论还是二级评论，根据parentId来判断，0为1级，其他二级
        if (review.getParentId() == 0){
            r.setParentId(review.getId());
        }else {
            r.setParentId(review.getParentId());
        }
        return zArticleReviewMapper.insert(r);
    }

    @Override
    @Transactional
    public int removeByIdTree(Long id) {
        ZArticleReview review = zArticleReviewMapper.selectById(id);
        //删除评论点赞日志数据
        LambdaQueryWrapper<ZPraiseLog> zPraiseLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        zPraiseLogLambdaQueryWrapper.eq(ZPraiseLog::getReviewId,review.getId());
        zPraiseLogMapper.delete(zPraiseLogLambdaQueryWrapper);
        //判断有无父评论
        Long parentId = review.getParentId();

        if (!parentId.equals(0L)){
            //如果有父id，只删除当前评论
            return zArticleReviewMapper.deleteById(id);
        }
        //如果没有父id，说明此评论为一级评论，删除一级评论下的所有评论
        LambdaQueryWrapper<ZArticleReview> wrapper = new LambdaQueryWrapper<>();
        //删除数据库中所有父id=当前评论的id,也就是这条评论的所有子评论
        wrapper.eq(ZArticleReview::getParentId,review.getId());
        zArticleReviewMapper.delete(wrapper);
        //还要删除自己本身
        return zArticleReviewMapper.deleteById(id);

    }

    @Override
    public TableDataInfo selectReviewTreeUser(ZArticleReview zArticleReview) {
        Long contentId = zArticleReview.getContentId();
        TableDataInfo dataInfo = selectReviewTree(zArticleReview);
        //得到当前文章所有评论
        List<ZArticleReview> rows = (List<ZArticleReview>) dataInfo.getRows();

        //查询已经点赞过了的评论记录
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        LambdaQueryWrapper<ZPraiseLog> zPraiseLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        zPraiseLogLambdaQueryWrapper.eq(ZPraiseLog::getUserId,userId)
                .eq(ZPraiseLog::getArticleId,contentId);
        //得到当前用户，当前文章的所有评论点赞日志记录
        List<ZPraiseLog> zPraiseLogs = zPraiseLogService.list(zPraiseLogLambdaQueryWrapper);
        //这些都是当前用户在当前文章已经点赞了的评论数据
        List<Long> reviewIds = zPraiseLogs.stream().map(ZPraiseLog::getReviewId).collect(Collectors.toList());
        for (ZArticleReview row : rows) {
            //一级评论
            for (Long reviewId : reviewIds) {
                if (row.getId() == reviewId){
                    //此文章的评论记录已被当前用户点赞，标记当前评论
                    row.setStatus(1);
                }
            }

            //二级评论
            if (ObjectUtils.isNotEmpty(row.getChildren())){
                List<ZArticleReview> children = row.getChildren();
                for (ZArticleReview child : children) {
                    for (Long reviewId : reviewIds) {
                        if (child.getId() == reviewId ){
                            //标记为 已点赞
                            child.setStatus(1);
                        }
                    }
                }
                row.setChildren(children);
            }
        }

        return dataInfo;
    }

    @Override
    public List<reviewData> getReviewList(ZArticleReview zArticleReview) {
        //查询当前文章的所有评论
        Long contentId = zArticleReview.getContentId();
        LambdaQueryWrapper<ZArticleReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ZArticleReview::getContentId,contentId);
        List<ZArticleReview> zArticleReviews = zArticleReviewMapper.selectList(wrapper);
        //封装前端需要的格式数据
        List<reviewData> reviewDataList = new ArrayList<>();
        for (ZArticleReview articleReview : zArticleReviews) {
            reviewData reviewData = new reviewData();
            reviewData.setId(articleReview.getId());
            if (articleReview.getParentId() == 0L){
                reviewData.setParent_id(null);
            }else {
                reviewData.setParent_id(articleReview.getParentId());
            }

            reviewData.setReply_id(articleReview.getReplyUserId());
            reviewData.setReply_name(articleReview.getReplyUserName());
            reviewData.setUser_id(articleReview.getUserId());
            reviewData.setUser_name(articleReview.getUserName());
            //得到用户头像
            SysUser sysUser = sysUserMapper.selectUserById(articleReview.getUserId());
            reviewData.setUser_avatar("http://localhost:9090" + sysUser.getAvatar());
            reviewData.setUser_content(articleReview.getCommentDetails());
            reviewData.setCreate_time(articleReview.getCommentDate());
            //设置点赞数
            reviewData.setLike_count(articleReview.getLikeNum());
            /**
             * 判断当前用户是否已经给当前评论点赞
             * 1.查询记录表当中是否记录了评论点赞数据，有：已经点过赞，无：没有点过赞
             *
             */
            LambdaQueryWrapper<ZPraiseLog> zPraiseLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
            zPraiseLogLambdaQueryWrapper.eq(ZPraiseLog::getUserId,zArticleReview.getUserId())
                    .eq(ZPraiseLog::getReviewId,articleReview.getId());
            ZPraiseLog zPraiseLog = zPraiseLogService.getOne(zPraiseLogLambdaQueryWrapper);
            if (ObjectUtils.isNotEmpty(zPraiseLog)) {
                //已经点赞
                reviewData.setIs_like(true);
            }else {
                //没有点赞
                reviewData.setIs_like(false);
            }
            reviewDataList.add(reviewData);
        }
        return reviewDataList;
    }

    @Override
    @Transactional
    public Long insertReviewReviewId(ZArticleReview zArticleReview) {
        //接收评论文章的id和内容
        Long articleId = zArticleReview.getContentId();
        String commentDetails = zArticleReview.getCommentDetails();
        ZArticleReview review = new ZArticleReview();
        review.setContentId(articleId);
        review.setCommentDetails(commentDetails);
        review.setParentId(0L);
        review.setUserId(zArticleReview.getUserId());
        review.setUserName(zArticleReview.getUserName());
        review.setLikeNum(0L);
        review.setCommentDate(new Date());
        //判断是不是作者
        ZArticle zArticle = zArticleService.getById(articleId);
        //如果评论是作者
        if (zArticle.getAuthorId().equals(zArticleReview.getUserId())){
            review.setContentFlag(1L);
        }else {
            review.setContentFlag(2L);
        }
        zArticleReviewMapper.insert(review);
        //文章评论数量+1
        zArticle.setEvaluate(zArticle.getEvaluate()+1);
        zArticleService.updateById(zArticle);
        return review.getId();
    }

    @Override
    @Transactional
    public Long saveReviewReviewId(ZArticleReview zArticleReview) {
        //得到评论内容和被回复的评论id
        String commentDetails = zArticleReview.getCommentDetails();
        Long id = zArticleReview.getId();

        ZArticleReview r = new ZArticleReview();

        //查询所要回复的评论
        ZArticleReview review = zArticleReviewMapper.selectById(id);
        r.setContentId(review.getContentId());
        r.setUserId(zArticleReview.getUserId());
        r.setUserName(zArticleReview.getUserName());
        r.setCommentDetails(commentDetails);
        r.setCommentDate(new Date());
        //回复的评论id
        r.setReplyCommentId(review.getId());
        r.setReplyUserId(review.getUserId());
        r.setReplyUserName(review.getUserName());

        //判断是不是作者
        ZArticle zArticle = zArticleService.getById(review.getContentId());
        zArticle.setEvaluate(zArticle.getEvaluate()+1);
        //如果评论是作者
        if (zArticle.getAuthorId().equals(zArticleReview.getUserId())){
            r.setContentFlag(1L);
        }else {
            r.setContentFlag(2L);
        }

        //判断是回复一级评论还是二级评论，根据parentId来判断，0为1级，其他二级
        if (review.getParentId() == 0){
            r.setParentId(review.getId());
        }else {
            r.setParentId(review.getParentId());
        }
        zArticleReviewMapper.insert(r);
        return r.getId();
    }

}
